package tjtss50;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;

public class XHTMLParser {
private String data;
private static String[] validTags = {"h1","h2","p","ul","li","ol","img"};
private String parsedData;
private List<File> recentFiles = new LinkedList<File>();

  public XHTMLParser(String string) {
    data = string;
    this.isValid();
  }
  
  public XHTMLParser(String data, File file) throws IOException {
    createNewFileWith(data, file);
  }

  public XHTMLParser(File file) throws FileNotFoundException, IOException {
    this.data = readFrom(file);
    this.isValid();
  }

  public XHTMLParser() {
  }

  public String readFrom(File file) throws IOException {
    FileReader inputStream = null;
    StringBuffer content = new StringBuffer();

    try {
      inputStream = new FileReader(file);

      int c;
      while ((c = inputStream.read()) != -1) {
        content.append((char)c);
      }
    } finally {
      if (inputStream != null) {
        inputStream.close();
      }
    }
    data = content.toString();
    return data;  
  }
  
  public boolean writeTo(File file) throws IOException{
    java.io.FileWriter fw = null;
    java.io.BufferedWriter bw = null;
      try {
        fw = new java.io.FileWriter(file);
        bw = new java.io.BufferedWriter(fw);
        bw.write(this.data,0,data.length());
      } catch (IOException e) {
        //e.printStackTrace();
        throw e;
      }
    finally{
      bw.close();
      fw.close();
    }
    return true;
  }
  
  public String getData() {
    return data;
  }
  
  public String getParsedData(){
    return parsedData;
  }

  public boolean isValid() {
    java.util.Stack<String> tags = new java.util.Stack<String>();
    StringBuffer workdata = new StringBuffer(data.trim());
    // Nopea tarkistus yleiselle validisuudelle   
    if(!(workdata.charAt(0)=='<') || !(workdata.charAt(workdata.length()-1)=='>'))
      return false;
    StringBuffer tag = null;
    try{
      while(workdata.indexOf("<") >= 0){
        tag = new StringBuffer(getFirstTag(workdata));
        String tagName = isValidTag(tag);
        if(isEndTag(tag)){
          // Onko lopputagille parina sopiva alkutagi?
          String temp = tags.pop();
          if(! temp.equals(tagName) )
            return false;
        }
        else if(isSingleTag(tag));
        else
          tags.push(tagName);
         
        removeTag(workdata, tag.toString());
      }
    }
    catch(Exception e){
      return false;
    }
    parsedData = workdata.toString();
    return true;
  }

  public static String getFirstTag(StringBuffer workdata) throws InvalidXHTMLException{
    int begin = workdata.indexOf("<");
    int end = workdata.indexOf(">");
    if(begin == -1 || end == -1)
      throw new InvalidXHTMLException();
    StringBuffer tagcontent = new StringBuffer( workdata.substring(begin,end+1).trim() );
    //if(tagcontent.indexOf(" ") >=0)
      //tagcontent = new StringBuffer( tagcontent.substring(0,tagcontent.indexOf(" ")));
    return tagcontent.toString();

  }

  public static boolean isSingleTag(StringBuffer buffer) throws InvalidXHTMLException{
    if(buffer.length() < 3)
      throw new InvalidXHTMLException();
    if(buffer.charAt(buffer.length()-2) == '/')
      return true;
    
    return false;
  }

  public static boolean isEndTag(StringBuffer buffer) throws InvalidXHTMLException{
    if(buffer.length() < 3)
      throw new InvalidXHTMLException();
    if(buffer.charAt(1) == '/')
      return true;
    
    return false;
  }

  public static String removeTag(StringBuffer buffer,String tag) {
    buffer.delete(buffer.indexOf("<"), buffer.indexOf("<")+tag.length());
    return buffer.toString();
  }

  public static String isValidTag(StringBuffer buffer) throws InvalidXHTMLException{
    String worktag;
    if(!buffer.toString().endsWith(">") || !buffer.toString().startsWith("<"))
      throw new InvalidXHTMLException();
    //try{
      if(isSingleTag(buffer))
        worktag = buffer.substring(1,buffer.length()-2).trim();
      else if(isEndTag(buffer))
        worktag = buffer.substring(2,buffer.length()-1).trim();
      else
        worktag = buffer.substring(1,buffer.length()-1).trim();
    //}
    //catch(Exception e){return false;}
    if(worktag.indexOf(" ") >= 0)
      worktag = worktag.substring(0,worktag.indexOf(" "));
    for(int i = 0;i< validTags.length;i++)
      if(worktag.equals(validTags[i]))
        return worktag;
    throw new InvalidXHTMLException();
  }

  public List<File> getRecentFiles() {
    return recentFiles;
  }

  public void createNewFileWith(String data, File file) throws IOException {
    this.data = data;
    isValid();
    writeTo(file);
    recentFiles.add(file);
  }

  public void removeFile(File file) {
    file.delete();
    recentFiles.remove(file);
  }
}
